<template>
  <a-modal v-model:visible="visible" :title="title" :mask-closable="false" :esc-to-close="false" draggable
    :width="width >= 600 ? 600 : '100%'" @before-ok="save" @close="reset">
    <GiForm ref="formRef" v-model="form" :options="options" :columns="columns">
      <!-- 不使用默认插槽替换上传组件，让GiForm正常渲染上传按钮 -->
      <!-- 已上传文件列表将在自定义组件外部显示 -->
    </GiForm>
    <!-- 自定义文件列表显示区域 - 在表单外部但在模态框内部 -->
    <div v-if="Array.isArray(form.testPlanFile) && form.testPlanFile.length > 0" class="custom-file-list">
      <h4 style="margin-bottom: 8px;">已上传文件：</h4>
      <div v-for="(file, index) in form.testPlanFile" :key="index" class="file-item">
        <a :href="file" target="_blank" rel="noopener noreferrer" class="file-link">
          预览文件 {{ index + 1 }}
        </a>
        <a-button type="text" danger @click="deleteFile('testPlanFile', index)">删除</a-button>
      </div>
    </div>
  </a-modal>
  <!-- 文件预览 -->
  <FilePreview ref="filePreviewRef" />
</template>

<script setup lang="ts">
import { Message } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import { useResetReactive } from '@/hooks'
import { useDict, useNickname, useProjectName, useDeviceName, useLocName } from '@/hooks/app'
import { addInfo, getInfo, updateInfo } from '@/apis/task/info'
import { type Columns, type ColumnsItem, GiForm, type Options } from '@/components/GiForm'

// 文件预览
// 文件处理
import { type FileItem } from '@/apis'
import type { ExcelConfig } from '@/components/FilePreview/type'
import { OfficeTypes } from '@/constant/file'

const emit = defineEmits<{
  (e: 'save-success'): void
}>()

const { width } = useWindowSize()

const dataId = ref('')
const visible = ref(false)
const isUpdate = computed(() => !!dataId.value)
const title = computed(() => (isUpdate.value ? '修改测试任务' : '新增测试任务'))
const formRef = ref<InstanceType<typeof GiForm>>()
const { task_status } = useDict('task_status')

const { nicknameList, getNicknameList } = useNickname()
const { projectNameList, getProjectNameList } = useProjectName()
const { locNameList, getLocNameList } = useLocName()
// const { deviceNameList, getDeviceNameList } = useDeviceName()

const options: Options = {
  form: { size: 'large' },
  btns: { hide: true },
}

const [form, resetForm] = useResetReactive({
  testPlanFile: [] // 初始化为空数组，用于存储多个文件URL
})

const columns: Columns = reactive([
  {
    label: '参与者',
    field: 'participantIds',
    type: 'select',
    options: nicknameList,
    props: {
      multiple: true,
      allowClear: true,
      allowSearch: true,
    },
    rules: [{ required: true, message: '请选择参与者' }]
  },
  {
    label: '责任人',
    field: 'dutyIds',
    type: 'select',
    options: nicknameList,
    props: {
      multiple: true,
      allowClear: true,
      allowSearch: true,
    },
    rules: [{ required: true, message: '请选择责任人' }]
  },
  {
    label: '任务名称',
    field: 'name',
    type: 'input',
    rules: [{ required: true, message: '请输入任务名称' }]
  },
  {
    label: '项目名称',
    field: 'projectId',
    type: 'select',
    options: projectNameList,
    props: {
      allowSearch: true,
    },
    rules: [{ required: true, message: '请输入项目名称' }]
  },
  {
    label: '设备地点名称',
    field: 'locId',
    type: 'select',
    options: locNameList,
    props: {
      allowSearch: true,
    },
    rules: [{ required: true, message: '请输入设备地点名称' }]
  },
  // {
  //   label: '设备名称',
  //   field: 'deviceId',
  //   type: 'select',
  //   options: deviceNameList,
  //   props: {
  //     allowSearch: true,
  //   },
  //   rules: [{ required: true, message: '请输入设备名称' }]
  // },
  {
    label: '计划开始时间',
    field: 'planStartTime',
    type: 'date-picker',
    props: {
      showTime: true,
    },
    rules: [{ required: true, message: '请输入计划开始时间' }]
  },
  {
    label: '计划结束时间',
    field: 'planEndTime',
    type: 'date-picker',
    props: {
      showTime: true,
    },
    rules: [{ required: true, message: '请输入计划结束时间' }]
  },
  {
    label: '实际开始时间',
    field: 'actualStartTime',
    type: 'date-picker',
    props: {
      showTime: true,
    },
    rules: [{ required: true, message: '请输入实际开始时间' }]
  },
  {
    label: '实际结束时间',
    field: 'actualEndTime',
    type: 'date-picker',
    props: {
      showTime: true,
    },
    rules: [{ required: true, message: '请输入实际结束时间' }]
  },
  {
    label: '状态',
    field: 'status',
    type: 'radio-group',
    options: task_status,
    rules: [{ required: true, message: '请输入状态' }]
  },
  // {
  //   label: '测试模板ID',
  //   field: 'templateId',
  //   type: 'input',
  //   rules: [{ required: true, message: '请输入测试模板ID' }]
  // },
  {
    label: '备注',
    field: 'fileTopic',
    type: 'input',
  },
  {    
    label: '文件',
    field: 'testPlanFile',
    type: 'upload',
    props: {
      accept: '.doc,.docx,.pdf',
      multiple: false, // 单文件上传
      action: '/api/common/file',
      showUploadList: false, // 隐藏默认的上传列表
      // 关键配置：确保上传按钮始终可见，即使已上传文件
      showButton: true,
      // 上传成功回调
      onSuccess: (response: any) => {
        Message.success('上传成功')
        // 确保testPlanFile始终是数组
        if (!Array.isArray(form.testPlanFile)) {
          form.testPlanFile = []
        }
        // 将新文件URL添加到数组中
        form.testPlanFile.push(response.response.data.url)
        // 强制数组更新，确保视图能正确显示所有文件
        form.testPlanFile = [...form.testPlanFile]
      },
    },
    rules: [{ required: false, message: '请上传试验测试方案' }]
  },
])

// 重置
const reset = async () => {
  formRef.value?.formRef?.resetFields()
  resetForm()
  if (!nicknameList.value.length) {
    await getNicknameList()
  }
  if (!projectNameList.value.length) {
    await getProjectNameList()
  }
  if (!locNameList.value.length) {
    await getLocNameList()
  }
  // id不匹配代码出错
  // if (!deviceNameList.value.length) {
  //   await getDeviceNameList()
  // }
}

// 保存
const save = async () => {
  try {
    const isInvalid = await formRef.value?.formRef?.validate()
    if (isInvalid) return false
    
    // 创建表单数据的深拷贝，避免直接修改原始form数据
    const formData = { ...form }
    
    // 将testPlanFile数组转换为JSON字符串格式提交给后端
    if (Array.isArray(formData.testPlanFile)) {
      formData.testPlanFile = JSON.stringify(formData.testPlanFile)
    }
    
    if (isUpdate.value) {
      await updateInfo(formData, dataId.value)
      Message.success('修改成功')
    } else {
      await addInfo(formData)
      Message.success('新增成功')
    }
    emit('save-success')
    return true
  } catch (error) {
    return false
  }
}

// 新增
const onAdd = async () => {
  reset()
  dataId.value = ''
  visible.value = true
}

// 修改
const onUpdate = async (id: string) => {
  reset()
  dataId.value = id
  const { data } = await getInfo(id)
  // 复制数据并处理testPlanFile
  const infoData = { ...data }
  
  // 后端传来的testPlanFile一定是JSON数组字符串，需要解析为数组用于前端显示
  if (infoData.testPlanFile && typeof infoData.testPlanFile === 'string') {
    try {
      infoData.testPlanFile = JSON.parse(infoData.testPlanFile)
    } catch (e) {
      // 解析失败时设置为空数组
      infoData.testPlanFile = []
    }
  }
  
  Object.assign(form, infoData)
  visible.value = true
}

// 删除文件
const deleteFile = (field: string, index: number) => {
  // Ensure form[field] is an array before using splice
  if (!Array.isArray(form[field])) {
    form[field] = []
  }
  // Check if index is valid
  if (index >= 0 && index < form[field].length) {
    form[field].splice(index, 1)
    Message.success('文件已删除')
  }
}

// 根据FileItem进行预览
const filePreviewRef = ref()
const handleClickFile = (item: FileItem) => {
  if (OfficeTypes.includes(item.extension)) {
    const excelConfig: ExcelConfig = {
      xls: item.extension === 'xls',
      minColLength: 0,
      minRowLength: 0,
      widthOffset: 10,
      heightOffset: 10,
      beforeTransformData: (workbookData) => {
        return workbookData
      },
      transformData: (workbookData) => {
        return workbookData
      },
    }
    filePreviewRef.value.onPreview({
      fileInfo: { data: item.url, fileName: item.name, fileType: item.extension },
      excelConfig,
    })
  }
}

defineExpose({ onAdd, onUpdate })
</script>

<style scoped lang="scss">
.file-list {
  margin-top: 10px;
}

.file-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  padding: 8px;
  background-color: #f5f5f5;
  border-radius: 4px;
}

.file-link {
  color: #165dff;
  text-decoration: none;
  margin-right: 12px;
  padding: 4px 8px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.file-link:hover {
  background-color: #e6f0ff;
  text-decoration: underline;
}

.file-item a-button {
  margin-left: auto;
}
</style>
